package com.android.fragmentdemo.defineviews
import android.animation.ObjectAnimator
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.Toast
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.get
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.fragmentdemo.R
import com.android.fragmentdemo.adapters.RvListDataAdapter
import com.hengfoxwolf.commonbase.base.databeans.ItemData
import com.hengfoxwolf.commonbase.base.databeans.ItemListData
import com.android.fragmentdemo.databinding.ExpandLayoutBody2Binding
import com.android.fragmentdemo.databinding.ExpandLayoutTopBinding
import com.android.fragmentdemo.findBinding
import com.android.fragmentdemo.showToast
import java.util.concurrent.Executors
import kotlin.math.abs

class ExpandViewGroup @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : ViewGroup(context, attributeSet), ArrowView.ITouchCallback {

    private var mTotalWidth = 0
    private var mTotalHeight = 0

    private var mChildPadding = context.resources.getDimension(R.dimen.dp_10)

    private var mBaseShowLimitedHeight = context.resources.getDimension(R.dimen.dp_30).toInt()
    private var mShowLimitedHeight = context.resources.getDimension(R.dimen.dp_245).toInt()

    private val mChildHeightMap = mutableMapOf<Int, Int>()

    private val mExpandLayoutTopBinding: ExpandLayoutTopBinding
    private var mExpandLayoutBody2Binding: ExpandLayoutBody2Binding? = null

    private var addOrDelete = true

    private var mItemData: ItemData? = null
    private var mItemListData: ItemListData? = null

    init {
        setBackgroundColor(context.resources.getColor(R.color.color_0BABF3))
        mExpandLayoutTopBinding = findBinding(R.layout.expand_layout_top)
        mExpandLayoutTopBinding.tvLeftTitle.setOnClickListener {
            mItemListData?.let {
                context.showToast(it.title)
            }
        }
        mExpandLayoutTopBinding.rightArrowView.setTouchCallback(this)
        addView(
            mExpandLayoutTopBinding.root,
            MarginLayoutParams(MarginLayoutParams.MATCH_PARENT, MarginLayoutParams.WRAP_CONTENT)
        )
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        mChildHeightMap.clear()
        for (i in 0.until(childCount)) {
            val child = get(i)
            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0)
            mChildHeightMap[i] = child.measuredHeight + mChildPadding.toInt()
            Log.d(TAG, "$TAG---child.measuredHeight---${child.measuredHeight}")
        }

        mTotalWidth = when (MeasureSpec.getMode(widthMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(widthMeasureSpec)
            }

            else -> {
                context.resources.getDimension(R.dimen.dp_60).toInt()
            }
        }

        mTotalHeight = when (MeasureSpec.getMode(heightMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(heightMeasureSpec)
            }

            else -> {
                var allChildHeight = 0
                for ((_, value) in mChildHeightMap) {
                    allChildHeight += value
                }
                allChildHeight
            }
        }

        setMeasuredDimension(
            MeasureSpec.makeMeasureSpec(mTotalWidth, MeasureSpec.EXACTLY),
            MeasureSpec.makeMeasureSpec(mTotalHeight, MeasureSpec.EXACTLY)
        )
    }

    override fun onLayout(force: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        var layoutTotalHeight = 0
        for (i in 0.until(childCount)) {
            when (i) {
                0 -> {
                    val child = get(i)
                    val childWidth = child.measuredWidth
                    val childHeight = child.measuredHeight
                    val childTotalHeight = mChildHeightMap[i] ?: 0
                    child.layout(
                        0,
                        (childTotalHeight - childHeight) / 2,
                        childWidth,
                        childHeight + (childTotalHeight - childHeight) / 2
                    )
                    layoutTotalHeight += childTotalHeight
                }
                1 -> {
                    val child = get(i)
                    val childWidth = child.measuredWidth
                    val childHeight = child.measuredHeight
                    val childTotalHeight = mChildHeightMap[i] ?: 0
                    child.layout(
                        0,
                        layoutTotalHeight /*+ (childTotalHeight - childHeight) / 2*/,
                        childWidth,
                        layoutTotalHeight + childHeight + (childTotalHeight - childHeight) / 2
                    )
                    layoutTotalHeight += childTotalHeight
                }
            }
        }
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }

    override fun onTouchUp() {
        Log.d(TAG,"$TAG --- onTouchUp")
        Log.d(TAG,"is null---${mItemData == null}")
        if (addOrDelete) {
//            if (childBodyView == null) {
//                childBodyView = LayoutInflater.from(context).inflate(R.layout.expand_layout_body, this, false)
//                val tvBodyViewContent : AppCompatTextView = childBodyView!!.findViewById(R.id.tv_body_content)
//                mItemData?.let {
//                    tvBodyViewContent.text = it.detailDesc
//                }
//            }

            startAnimation(0F, 90F)

            if (mExpandLayoutBody2Binding == null) {
                mExpandLayoutBody2Binding = findBinding(R.layout.expand_layout_body2)
                val rvBodyViewLayoutParams =
                    mExpandLayoutBody2Binding!!.expandViewRv.layoutParams as FrameLayout.LayoutParams
                val mItemListDataCount = mItemListData?.itemList?.size ?: 0
                val condition  = mItemListDataCount > SHOW_ITEM_COUNT
                if (condition) {
                    rvBodyViewLayoutParams.height = mShowLimitedHeight
                } else {
                    rvBodyViewLayoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT
                }
                mExpandLayoutBody2Binding!!.expandViewRv.layoutParams = rvBodyViewLayoutParams
                mExpandLayoutBody2Binding!!.expandViewRv.apply {
                    layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
                    adapter = RvListDataAdapter().apply {
                        mItemListData?.let { setItemDataSet(it.itemList) }
                    }
                }
            }

            addView(
                mExpandLayoutBody2Binding!!.root,
                MarginLayoutParams(
                    MarginLayoutParams.MATCH_PARENT,
                    MarginLayoutParams.WRAP_CONTENT
                )
            )
        } else {
            mExpandLayoutBody2Binding?.let {
                removeView(it.root)
                startAnimation(90F, 0F)
            }
        }
        addOrDelete = !addOrDelete
    }

    private fun startAnimation(startAngle: Float, endAngle: Float) {
        val animation = ObjectAnimator.ofFloat(mExpandLayoutTopBinding.rightArrowView, "rotation", startAngle, endAngle)
        animation.duration = 100
        animation.start()
    }

    fun setItemData(itemData: ItemData?) {
        Log.d(TAG,"is null---${itemData == null}")
        mItemData = itemData
        mItemData?.let {
            mExpandLayoutTopBinding.tvLeftTitle.text = it.title
        }
    }

    fun setItemData(itemData: ItemListData?) {
        Log.d(TAG,"is null---${itemData == null}")
        mItemListData = itemData
        mItemListData?.let {
            mExpandLayoutTopBinding.tvLeftTitle.text = it.title
        }
    }

    companion object {
        const val TAG = "ExpandViewGroup"
        const val SHOW_ITEM_COUNT = 10
    }
}